package asem.ast.expresiones;

import alex.Token;
import asem.excepciones.ExcepcionTiposIncompatibles;
import asem.tablaSimbolos.tipo.Tipo;
import asem.tablaSimbolos.tipo.TipoBoolean;
import asem.tablaSimbolos.tipo.TipoInt;
import asem.tablaSimbolos.tipo.TipoMetodo;

public class NodoExpresionBinaria extends NodoExpresion {
	protected NodoExpresion primeraExp;
	protected NodoExpresion segundaExp;
	protected Token operador;

	public NodoExpresionBinaria(Token op, NodoExpresion exp1, NodoExpresion exp2) {
		operador = op;
		primeraExp = exp1;
		segundaExp = exp2;
	}

	@Override
	public TipoMetodo chequeoSentencias() {

		Tipo t1 = (Tipo) primeraExp.chequeoSentencias();
		Tipo t2 = (Tipo) segundaExp.chequeoSentencias();

		switch (operador.getTipo()) {
		case O_Suma:
		case O_Resta:
		case O_Multiplicacion:
		case O_Division:
		case O_Modulo:
			// Si el operador es +, -, *, /, %, se espera que t1 y t2 sean ints
			if (t1.equals(TipoInt.TIPO) && t2.equals(TipoInt.TIPO))
				return TipoInt.TIPO;
			break;
		case O_And:
		case O_Or:
			// Si el operador es && o ||, se espera que t1 y t2 sean booleans
			if (t1.equals(TipoBoolean.TIPO) && t2.equals(TipoBoolean.TIPO))
				return TipoBoolean.TIPO;
			break;
		case O_Menor:
		case O_Mayor:
		case O_MayorIgual:
		case O_MenorIgual:
			// Si el operador es <, <=, >, >=, se espera que t1 y t2 sean ints
			if (t1.equals(TipoInt.TIPO) && t2.equals(TipoInt.TIPO))
				return TipoBoolean.TIPO;
			break;
		case O_Igual:
		case O_Distinto:
			// Si el operador es != o ==, entonces se espera que t1 y t2 sean
			// tipos compatibles
			if (t1.compatible(t2))
				return TipoBoolean.TIPO;
		default:
			break;
		}

		throw new ExcepcionTiposIncompatibles(t1, t2, operador);
	}
}
